home *** CD-ROM | disk | FTP | other *** search
/ Amiga Collections: Various / DevDisk 65 (1989)(DevWare PD).zip / DevDisk 65 (1989)(DevWare PD).adf / mypixel / pixel.asm < prev    next >
Assembly Source File  |  1990-07-11  |  6KB  |  145 lines

  1.     ;  Routine to draw one pixel at desired location.
  2.     ;  After the pedantic Geodesic Publications code, Linesdemo.
  3.     ;  C call is   pixel ( &bitmap, color number, x, y );
  4.     ;  Bitmap pointer passed on stack to facilitate dual-playfield calls.
  5.     ;  Compiler = Manx 3.6A
  6.  
  7.     ;  Thomas J. Eshelman   Reading, Pa.    12/20/88
  8.  
  9.                                  CSEG
  10.  
  11.                             public   _pixel
  12.  
  13.                                  DSEG
  14.  
  15. bm_BytesPerRow equ   0
  16. bm_Depth       equ   5
  17. bm_Planes      equ   8
  18.  
  19.                                  CSEG
  20. _pixel:
  21.  
  22.    movem.l  d2-d7/a2-a6,-(sp)          Save non-scratch registers.
  23.  
  24.     ;At this point, we have 44 bytes for the 11 registers and 4 bytes the
  25.     ;system used to save the return address when we called _pixel between
  26.     ;us and the arguments we passed and want to retrieve from the stack.
  27.     ;Hence, the first argument is located 48 bytes above the bottom.
  28.     ;This is because the stack decreases as it gets larger.  (It was invented
  29.     ;by an Congressional Committee, you see.)  The LAST argument saved to the
  30.     ;stack is the FIRST one available to come off.  Hence, the first one to
  31.     ;come off, the one with the lowest address, is the bitmap pointer.
  32.  
  33.    move.l   48(a7),a5                  Pointer to desired bitmap.
  34.    movem.w  52(a7),d0-d2               MOVEM pops args in SAME order pushed.
  35.  
  36.    move.w   d0,d3                      Copy color value for the helluva it.
  37.  
  38.    move.w   d2,d7                      Copy Y coordinate.
  39.    mulu     bm_BytesPerRow(a5),d7      Byte offset of line containing Y.
  40.  
  41.    ;d7 now holds the offset value, in number of bytes from the beginning of
  42.    ;each display plane, of the first byte of the line in which we find the
  43.    ;'Y' coordinate.  All we need do now is find out how far to the right, on
  44.    ;this line, of course, we must move in order to locate 'X' coordinate.
  45.  
  46.    move.w   d1,d4                      Copy X coordinate.
  47.  
  48.    ;The next 2 instructs divide X by 8 in order to convert BITS (the coord.
  49.    ;being expressed in terms of bits) into BYTES.  We have the second step
  50.    ;to guarantee an even result.  (Shifting is much faster than division).
  51.  
  52.    lsr.w    #4,d4
  53.    lsl.w    #1,d4
  54.  
  55.    ;The resulting base offset from the beginning of a line is added to the
  56.    ;the Y offset so we now have the offset of the byte in the plane that
  57.    ;we want to use to draw the pixel.  From here on,  we must advance bit
  58.    ;by bit (yuk, yuk, yuk!).
  59.  
  60.    add.w    d4,d7
  61.    ext.l    d7
  62.  
  63.    move.w   d1,d4                      Recopy X coordinate.
  64.  
  65.    ;This simple move yields how many BITS further right we must advance
  66.    ;prior to drawing the pixel.  Consider an X value of 150.  This is binary
  67.    ;1001 0110.  Divided by 8 is 18 with 6 left over.  So we will move left
  68.    ;18 bytes followed by 6 bits to draw.  The number of those bits we must
  69.    ;advance is necessarily contained in the rightmost nybble. Please extract.
  70.  
  71.    andi.w   #$f,d4                     Thank you.
  72.  
  73.    ;Set a bit in the high order byte of a register word that will represent
  74.    ;the bit to be moved right, if at all.  This bit represents the pixel we
  75.    ;will draw or erase.  Obviously, we then shift this bit into the exact
  76.    ;position we determined by the algorithm above. (In the above example,
  77.    ;this would be 6 bits right, which yields a literal hex value of $0200.
  78.    ;Don't worry about 'value'.  That is for illustration only.  We are only
  79.    ;concerned with the physical bit position.)
  80.  
  81.    move.w   #$8000,d5
  82.    lsr.w    d4,d5
  83.  
  84.    move.w   d5,d6                      d5 has the OR mask for pixel draw.
  85.                                             ;0000 0010 0000 0000
  86.    not.w    d6                         Prepare an AND mask for pixel erase.
  87.                                             ;1111 1101 1111 1111
  88.  
  89.    move.b   bm_Depth(a5),d0            Number of planes to draw into.
  90.    ext.w    d0
  91.  
  92.    subq.w   #1,d0                      Subtract one from Depth for dbra.
  93.  
  94.    clr.w    d1                         Actual Depth or Plane counter.
  95.  
  96. 10$:
  97.  
  98.    ;Multiply the counter by 4 and add it to the PLANEPTR value so that it
  99.    ;points to the next plane.  (0, 4, 8, 12, 16 byte offsets).  bm_Planes is
  100.    ;but an Array of Pointers, each pointing the to base of the next plane
  101.    ;comprising our bitmap.
  102.  
  103.    move.w   d1,d2
  104.    lsl.w    #2,d2                      Plane number times 4.
  105.  
  106.    movea.l  bm_Planes(a5,d2),a3        Retrieve this PLANEPTR.
  107.  
  108.    add.l    d7,a3                      Come to byte in which we shall plant
  109.    ;                                   our pixel.
  110.  
  111.    ;Achtung!  For the user's color choice, see to it that the bits for each
  112.    ;plane are set or reset so that the pixel of this color are in fact
  113.    ;displayed.  For example, if the user asked for color 5, then to draw a
  114.    ;pixel in that color in plane 1, we must be sure to zero the bit.
  115.  
  116.    btst     d1,d3                      Test the color bit in our plane.
  117.    beq      20$                        Branch if unset.
  118.  
  119.    ;a3 points to the byte containing the coordinate.  However, we will OR a
  120.    ;WORD against this BYTE.  Observe, supra, it is the HIGH order BYTE of d5
  121.    ;and d6 that contain the 'shift mask' (which in our example is $0200.
  122.    ;That makes the high order byte of said word, $02).
  123.  
  124.    ;Observe, also, that with the 68000, the high byte of the register is the
  125.    ;lower address in memory.  Therefore, we are applying the mask to the
  126.    ;exact BYTE referenced by (a3) and to the byte above that, (which latter
  127.    ;is of no effect because it always gets ORed with zeros).
  128.  
  129.    or.w     d5,(a3)                    Set the coordinate bit.  Behold!!
  130.    bra      30$                        Test next plane.
  131.  
  132. 20$:
  133.  
  134.    and.w    d6,(a3)                    Reset the coordinate bit.  Zap!
  135.  
  136. 30$:
  137.  
  138.    addq.w   #1,d1                      Advance to next plane, and to the
  139.    dbra     d0,10$                     corresponding binary color bit.
  140.  
  141.    movem.l  (sp)+,d2-d7/a2-a6          Pop user stack.
  142.    rts
  143.  
  144.                                   end
  145.